package halberd.filter;

import halberd.DataType;
import halberd.ImgFilter;
import halberd.data.ImgData;
import halberd.data.ImgDataFactory;

public class HalftoneFilter implements ImgFilter {

	public ImgData process(ImgData input) {
		if (!canProcess(input)) {
			return null;
		}
		ImgData result = ImgDataFactory.createImgData(input.getWidth(), input.getHeight());
		int[][][] ints = input.getDatas();
		halftone(ints, result.getDatas(), input.getWidth(), input.getHeight());
		result.setDataType(DataType.GRAY);
		return result;
	}

	private boolean canProcess(ImgData input) {
		if (input == null) {
			return false;
		}
		DataType dt = input.getDataType();
		if (dt == DataType.GRAY) {
			return true;
		}
		return false;
	}
	private void htpixel(int[][][] dst,int x,int y,int[][] mt,int W,int H)
	{
	    for (int i = x,i0=0; i < x + 3;++i,++i0 )
	    {
	        for (int j = y,j0=0; j < y + 3;++j,++j0 )
	        {
	        	dst[i][j][4]=mt[i0][j0];
	        }
	    }
	}
	private void halftone(int[][][] src, int[][][] dst, int W, int H) {

			
			int[][] table0={{0,0,0},{0,0,0},{0,0,0}};//0
			int[][] table1={ { 0, 0, 0 }, { 0, 127, 0 }, { 0, 0, 0 } }; //1
			int[][] table2={ { 0, 127, 0 }, { 0, 0, 0 }, { 127, 0, 127 } };//3
			int[][] table3={ { 0, 127, 0 }, { 127, 0, 127 }, { 0, 127, 0 } };//4
			int[][] table4={ { 0, 127, 0 }, { 127, 127, 127 }, { 0, 127, 0 } };//5
			int[][] table5={ { 127, 127, 127 }, { 127, 0, 127 }, { 127, 127, 127} };//8
			int[][] table6={ { 127, 127, 127 }, { 127, 127, 127 }, { 127, 127, 127} };//9
			int[][] table7={ { 127, 127, 127 }, { 127,255, 127 }, { 127, 127, 127} };//1
			int[][] table8={ { 255, 127, 255 }, { 127,127, 127 }, { 127, 255, 127} };//3
			int[][] table9={ { 127, 255, 127 }, { 255,127, 255 }, { 127, 255, 127} };//4
			int[][] table10={ { 127, 255, 127 }, { 255,255, 255 }, { 127, 255, 127} };//5
			int[][] table11={ { 255, 255, 255 }, { 255,127, 255 }, { 255, 255, 255} };//8
			int[][] table12={ { 255, 255, 255 }, { 255,255, 255 }, { 255, 255, 255} };//8
		    for (int i = 0; i < W-3;i+=3 )
		    {
		        for (int j = 0; j < H-3;j+=3 )
		        {
		            int count = 0;
		            for (int m = 0; m < 3;++m )
		            {
		                for (int n = 0; n < 3;++n )
		                {
		                    count+=src[i+m][j+n][4];
		                }
		            }
		            count = count / 9;
		            if (count<=5)
		            {
		                htpixel(dst,i,j,table0,W,  H);
		            }
		            else if (count<=25)
		            {
		                htpixel(dst,i,j,table1,W,  H);
		            }else if(count<=55)
		            {
		                 htpixel(dst,i,j,table2,W,  H);
		            }
		            else if (count<=75)
		            {
		                 htpixel(dst,i,j,table3,W,  H);
		            }
		            else if (count<=95)
		            {
		                htpixel(dst,i,j,table4,W,  H);
		            }
		            else if (count <= 115)
		            {
		                htpixel(dst,i,j,table5,W,  H);
		            }
		            else if (count <= 135)
		            {
		                 htpixel(dst,i,j,table6,W,  H);
		            }
		            else if (count <= 155)
		            {
		                 htpixel(dst,i,j,table7,W,  H);
		            }
					else if (count <= 175)
		            {
		                 htpixel(dst,i,j,table8,W,  H);
		            }
					else if (count <= 195)
		            {
		                 htpixel(dst,i,j,table9,W,  H);
		            }
					else if (count <= 215)
		            {
		                 htpixel(dst,i,j,table10,W,  H);
		            }
					else if (count <= 225)
		            {
		                 htpixel(dst,i,j,table11,W,  H);
		            }
		            else { 
		                 htpixel(dst,i,j,table12,W,  H);
		            }
		        }
		    }
		}
}
